home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / slip.c < prev    next >
C/C++ Source or Header  |  1992-05-14  |  6KB  |  255 lines

  1. /* @(#) $Header: slip.c,v 1.9 92/05/14 13:20:28 deyke Exp $ */
  2.  
  3. /* SLIP (Serial Line IP) encapsulation and control routines.
  4.  * Copyright 1991 Phil Karn
  5.  *
  6.  * Van Jacobsen header compression hooks added by Katie Stevens, UC Davis
  7.  *
  8.  *      - Feb 1991      Bill_Simpson@um.cc.umich.edu
  9.  *                      reflect changes to header compression calls
  10.  *                      revise status display
  11.  */
  12. #include <stdio.h>
  13. #include "global.h"
  14. #include "config.h"
  15. #include "mbuf.h"
  16. #include "iface.h"
  17. #include "ip.h"
  18. #include "slhc.h"
  19. #include "asy.h"
  20. #include "slip.h"
  21. #include "trace.h"
  22.  
  23. static struct mbuf *slip_decode __ARGS((struct slip *sp,int c));
  24. static struct mbuf *slip_encode __ARGS((struct mbuf *bp));
  25.  
  26. /* Slip level control structure */
  27. struct slip Slip[ASY_MAX];
  28.  
  29. /* Send routine for point-to-point slip */
  30. int
  31. slip_send(bp,iface,gateway,prec,del,tput,rel)
  32. struct mbuf *bp;        /* Buffer to send */
  33. struct iface *iface;    /* Pointer to interface control block */
  34. int32 gateway;          /* Ignored (SLIP is point-to-point) */
  35. int prec;
  36. int del;
  37. int tput;
  38. int rel;
  39. {
  40. #ifdef VJCOMPRESS
  41.     register struct slip *sp;
  42.     int type;
  43. #endif
  44.     if(iface == NULLIF){
  45.         free_p(bp);
  46.         return -1;
  47.     }
  48. #ifdef VJCOMPRESS
  49.     sp = &Slip[iface->xdev];
  50.     if (sp->escaped & SLIP_VJCOMPR) {
  51.         /* Attempt IP/ICP header compression */
  52.         type = slhc_compress(sp->slcomp,&bp,TRUE);
  53.         bp->data[0] |= type;
  54.     }
  55. #endif
  56.     return (*iface->raw)(iface,bp);
  57. }
  58. /* Send a raw slip frame */
  59. int
  60. slip_raw(iface,bp)
  61. struct iface *iface;
  62. struct mbuf *bp;
  63. {
  64.     struct mbuf *bp1;
  65.  
  66.     dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
  67.     iface->rawsndcnt++;
  68.     iface->lastsent = secclock();
  69.     if((bp1 = slip_encode(bp)) == NULLBUF){
  70.         return -1;
  71.     }
  72.     if (iface->trace & IF_TRACE_RAW)
  73.         raw_dump(iface,-1,bp1);
  74.     return Slip[iface->xdev].send(iface->dev,bp1);
  75. }
  76. /* Encode a packet in SLIP format */
  77. static
  78. struct mbuf *
  79. slip_encode(bp)
  80. struct mbuf *bp;
  81. {
  82.     struct mbuf *lbp;       /* Mbuf containing line-ready packet */
  83.     register char *cp;
  84.     int c;
  85.  
  86.     /* Allocate output mbuf that's twice as long as the packet.
  87.      * This is a worst-case guess (consider a packet full of FR_ENDs!)
  88.      */
  89.     lbp = alloc_mbuf((int16)(2*len_p(bp) + 2));
  90.     if(lbp == NULLBUF){
  91.         /* No space; drop */
  92.         free_p(bp);
  93.         return NULLBUF;
  94.     }
  95.     cp = lbp->data;
  96.  
  97.     /* Flush out any line garbage */
  98.     *cp++ = FR_END;
  99.  
  100.     /* Copy input to output, escaping special characters */
  101.     while((c = PULLCHAR(&bp)) != -1){
  102.         switch(c){
  103.         case FR_ESC:
  104.             *cp++ = FR_ESC;
  105.             *cp++ = T_FR_ESC;
  106.             break;
  107.         case FR_END:
  108.             *cp++ = FR_ESC;
  109.             *cp++ = T_FR_END;
  110.             break;
  111.         default:
  112.             *cp++ = c;
  113.         }
  114.     }
  115.     *cp++ = FR_END;
  116.     lbp->cnt = cp - lbp->data;
  117.     return lbp;
  118. }
  119. /* Process incoming bytes in SLIP format
  120.  * When a buffer is complete, return it; otherwise NULLBUF
  121.  */
  122. static
  123. struct mbuf *
  124. slip_decode(sp,c)
  125. register struct slip *sp;
  126. char c;         /* Incoming character */
  127. {
  128.     struct mbuf *bp;
  129.  
  130.     switch(uchar(c)){
  131.     case FR_END:
  132.         bp = sp->rbp_head;
  133.         sp->rbp_head = NULLBUF;
  134.         return bp;      /* Will be NULLBUF if empty frame */
  135.     case FR_ESC:
  136.         sp->escaped |= SLIP_FLAG;
  137.         return NULLBUF;
  138.     }
  139.     if(sp->escaped & SLIP_FLAG){
  140.         /* Translate 2-char escape sequence back to original char */
  141.         sp->escaped &= ~SLIP_FLAG;
  142.         switch(uchar(c)){
  143.         case T_FR_ESC:
  144.             c = FR_ESC;
  145.             break;
  146.         case T_FR_END:
  147.             c = FR_END;
  148.             break;
  149.         default:
  150.             sp->errors++;
  151.             break;
  152.         }
  153.     }
  154.     /* We reach here with a character for the buffer;
  155.      * make sure there's space for it
  156.      */
  157.     if(sp->rbp_head == NULLBUF){
  158.         /* Allocate first mbuf for new packet */
  159.         if((sp->rbp_tail = sp->rbp_head = alloc_mbuf(SLIP_ALLOC)) == NULLBUF)
  160.             return NULLBUF; /* No memory, drop */
  161.         sp->rcp = sp->rbp_head->data;
  162.     } else if(sp->rbp_tail->cnt == SLIP_ALLOC){
  163.         /* Current mbuf is full; link in another */
  164.         if((sp->rbp_tail->next = alloc_mbuf(SLIP_ALLOC)) == NULLBUF){
  165.             /* No memory, drop whole thing */
  166.             free_p(sp->rbp_head);
  167.             sp->rbp_head = NULLBUF;
  168.             return NULLBUF;
  169.         }
  170.         sp->rbp_tail = sp->rbp_tail->next;
  171.         sp->rcp = sp->rbp_tail->data;
  172.     }
  173.     /* Store the character, increment fragment and total
  174.      * byte counts
  175.      */
  176.     *sp->rcp++ = c;
  177.     sp->rbp_tail->cnt++;
  178.     return NULLBUF;
  179. }
  180. /* Process SLIP line input */
  181. void
  182. asy_rx(iface)
  183. struct iface *iface;
  184. {
  185.  
  186.     char *cp,buf[4096];
  187.     int cnt,xdev;
  188.     struct mbuf *bp;
  189.     register struct slip *sp;
  190.     int cdev;
  191.  
  192.     xdev = iface->xdev;
  193.     sp = &Slip[xdev];
  194.     cdev = sp->iface->dev;
  195.  
  196.     cnt = (*sp->get)(cdev,cp=buf,sizeof(buf));
  197.     while(--cnt >= 0){
  198.         if((bp = slip_decode(sp,*cp++)) == NULLBUF)
  199.             continue;       /* More to come */
  200.  
  201. #ifdef VJCOMPRESS
  202.         if (sp->iface->trace & IF_TRACE_RAW)
  203.             raw_dump(sp->iface,IF_TRACE_IN,bp);
  204.  
  205.         if (sp->escaped & SLIP_VJCOMPR) {
  206.             if ((c = bp->data[0]) & SL_TYPE_COMPRESSED_TCP) {
  207.                 if ( slhc_uncompress(sp->slcomp, &bp) <= 0 ) {
  208.                     free_p(bp);
  209.                     sp->errors++;
  210.                     continue;
  211.                 }
  212.             } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
  213.                 bp->data[0] &= 0x4f;
  214.                 if ( slhc_remember(sp->slcomp, &bp) <= 0 ) {
  215.                     free_p(bp);
  216.                     sp->errors++;
  217.                     continue;
  218.                 }
  219.             }
  220.         }
  221. #endif
  222.         if ( net_route( sp->iface, sp->type, bp ) != 0 ) {
  223.             free_p(bp);
  224.         }
  225.     }
  226. /*      free_p(bp); */
  227. }
  228.  
  229. /* Show serial line status */
  230. void
  231. slip_status(iface)
  232. struct iface *iface;
  233. {
  234.     struct slip *sp;
  235.  
  236.     if (iface->xdev > SLIP_MAX)
  237.         /* Must not be a SLIP device */
  238.         return;
  239.  
  240.     sp = &Slip[iface->xdev];
  241.     if (sp->iface != iface)
  242.         /* Must not be a SLIP device */
  243.         return;
  244.  
  245.     printf("  IN:\t%lu pkts\n", iface->rawrecvcnt);
  246. #ifdef VJCOMPRESS
  247.     slhc_i_status(sp->slcomp);
  248. #endif
  249.     printf("  OUT:\t%lu pkts\n", iface->rawsndcnt);
  250. #ifdef VJCOMPRESS
  251.     slhc_o_status(sp->slcomp);
  252. #endif
  253. }
  254.  
  255.